﻿/*Author：Lary Pan(itolmqj123@gmail.com)
 *Date  ：2016/7/13
 *Tips  ：工具类
 * */

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;

using System.Reflection;

public enum SlibingMode { first,last,index }

public class CHelper
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="parent"></param>
    /// <param name="child"></param>
    /// <param name="keepLocal"></param>
    /// <param name="slibingMode"></param>
    /// <param name="index"></param>
    public static void Attach(Transform parent, Transform child, bool keepLocal = true, SlibingMode slibingMode = SlibingMode.last,int index = 0)
    {
        if (parent == null || child == null) return;

        if (keepLocal)
        {
            Vector3 pos = child.localPosition;
            Quaternion rot = child.localRotation;
            Vector3 scale = child.localScale;
            child.parent = parent;
            child.localPosition = pos;
            child.localRotation = rot;
            child.localScale = scale;

        }
        else
        {
            child.parent = parent;
        }

        switch (slibingMode)
        {
            case SlibingMode.first:
                child.SetAsFirstSibling();
                break;
            case SlibingMode.last:
                child.SetAsLastSibling();
                break;
            case SlibingMode.index:
                child.SetSiblingIndex(index);
                break;
            default:
                break;
        }
            
    }

    /// <summary>
    /// 通过名称获取该结点
    /// </summary>
    /// <param name="node"></param>
    /// <param name="name"></param>
    /// <returns></returns>
    public static Transform FindNode(Transform node, string name)
    {
        if (node == null || node.name == name) return node;

        IEnumerator iter = node.GetEnumerator();
        while (iter.MoveNext())
        {
            Transform t = iter.Current as Transform;
            t = FindNode(t, name);
            if (t && t.name == name) return t;
        }
        return null;
    }

    public static T GetSafeComponent<T>(GameObject obj) where T : Component
    {
        T t = obj.GetComponent<T>();
        if (t == null) t = obj.AddComponent<T>();
        return t;
    }

    /// <summary>
    /// 根据长度刷新列表
    /// </summary>
    /// <param name="grid"></param>
    /// <param name="count"></param>
    /// <param name="itemPath"></param>
    /// <returns></returns>
    public static List<Transform> RefreshGrid(GridLayoutGroup grid, int count, string itemPath)
    {
        if (grid == null)
        {
            Debugger.Log("grid is null");
            return null;
        }
        List<Transform> list = new List<Transform>();

        List<Transform> childList = grid.GetChildList();
        int childCount = childList.Count;
        if (childCount == count)
        {
            list = childList;
        }
        else if (childCount > count)
        {
            list.AddRange(childList.GetRange(0, count));
            for (int i = count; i < childCount; i++)
            {
                childList[i].gameObject.SetActive(false);
                grid.RemoveChild(childList[i]);
            }
        }
        else
        {
            list.AddRange(childList);
            for (int i = childCount; i < count; i++)
            {
                ResHelper.LoadLocalRes(itemPath, obj =>
                {
                    if (obj != null)
                    {
                        Transform item = ((GameObject)obj).transform;
                        Attach(grid.transform, item);
                        list.Add(item);
                    }
                });
            }
        }

        for (int i = 0; i < count; i++)
        {
            if (!list[i].gameObject.activeSelf) 
                list[i].gameObject.SetActive(true);

            Toggle toggle = list[i].GetComponent<Toggle>();
            //the first one is default checked
            if (toggle) toggle.isOn = (i == 0);
                
        }
        grid.ResetPosition();   //这里扩展方法还没有实现
        return list;
    }


    #region json
    /// <summary>
    /// 解析包含类型 int/float/string/int[]/float[]/string[]/bool
    /// </summary>
    /// <param name="t"></param>
    /// <param name="jsonData"></param>
    /// <returns></returns>
    public static EntityBase DecodeJson(Type t, Dictionary<string, object> jsonData)
    {
        EntityBase instance = (EntityBase)Activator.CreateInstance(t);
        
        FieldInfo info = null;
        foreach (var item in jsonData)
        {
            info = t.GetField(item.Key);
            if (info == null) continue;

            if (typeof(int) == info.FieldType)
            {
                info.SetValue(instance, Convert.ToInt32(item.Value));
            }
            else if (typeof(float) == info.FieldType)
            {
                info.SetValue(instance, float.Parse(item.Value.ToString()));
            }
            else if (typeof(bool) == info.FieldType)
            {
                info.SetValue(instance, Convert.ToInt32(item.Value) == 1);
            }
            else if (typeof(string) == info.FieldType)
            {
                info.SetValue(instance, item.Value.ToString());
            }
            else
            {
                List<object> list = item.Value as List<object>;
                if (list.Count == 0) continue;

                if (typeof(int[]) == info.FieldType)
                {
                    int[] arr = new int[list.Count];
                    for (int i = 0; i < arr.Length; i++)
                    {
                        arr[i] = Convert.ToInt32(list[i]);
                    }
                    info.SetValue(instance, arr);
                }
                else if (typeof(float[]) == info.FieldType)
                {
                    float[] arr = new float[list.Count];
                    for (int i = 0; i < arr.Length; i++)
                    {
                        arr[i] = Convert.ToSingle(list[i]);
                    }
                    info.SetValue(instance, arr);
                }
                else if (typeof(string[]) == info.FieldType)
                {
                    string[] arr = new string[list.Count];
                    for (int i = 0; i < arr.Length; i++)
                    {
                        arr[i] = list[i].ToString();
                    }
                    info.SetValue(instance, arr);
                }
                else if (typeof(Vector3) == info.FieldType)
                {
                    Vector3 vec = Vector3.zero;
                    if (list.Count == 3)
                    {
                        vec.x = Convert.ToSingle(list[0]);
                        vec.y = Convert.ToSingle(list[1]);
                        vec.z = Convert.ToSingle(list[2]);
                    }
                    info.SetValue(instance, vec);
                }
            }
        }
        return instance;
    }
	#endregion
     


}
